/******************************************************************************
 * Copyright 2020 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/*
 * Copyright 2018-2019 Autoware Foundation. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file common.h
 * @brief MACRO for CUDA codes
 * @author Kosuke Murakami
 * @date 2019/02/26
 */

#pragma once

// headers in STL
#include <stdio.h>

// headers in CUDA/HIP
#if GPU_PLATFORM == NVIDIA
  #include <cuda_runtime_api.h>
#elif GPU_PLATFORM == AMD
  #include <hip/hip_runtime_api.h>
  #define cudaError_t hipError_t
  #define cudaFree hipFree
  #define cudaGetErrorString hipGetErrorString
  #define cudaMalloc hipMalloc
  #define cudaMemcpy hipMemcpy
  #define cudaMemcpyAsync hipMemcpyAsync
  #define cudaMemcpyDeviceToDevice hipMemcpyDeviceToDevice
  #define cudaMemcpyDeviceToHost hipMemcpyDeviceToHost
  #define cudaMemcpyHostToDevice hipMemcpyHostToDevice
  #define cudaMemset hipMemset
  #define cudaSetDevice hipSetDevice
  #define cudaStream_t hipStream_t
  #define cudaStreamCreate hipStreamCreate
  #define cudaStreamDestroy hipStreamDestroy
  #define cudaSuccess hipSuccess
#endif

namespace apollo {
namespace perception {
namespace lidar {

// using MACRO to allocate memory inside CUDA kernel
#define NUM_3D_BOX_CORNERS_MACRO 8
#define NUM_2D_BOX_CORNERS_MACRO 4
#define NUM_THREADS_MACRO 64  // need to be changed when num_threads_ is changed

#define DIVUP(m, n) ((m) / (n) + ((m) % (n) > 0))

#define GPU_CHECK(ans) \
  { GPUAssert((ans), __FILE__, __LINE__); }
inline void GPUAssert(cudaError_t code, const char* file, int line,
                      bool abort = true) {
  if (code != cudaSuccess) {
    fprintf(stderr, "GPUassert: %s %s %d\n", cudaGetErrorString(code), file,
            line);
    if (abort) exit(code);
  }
}

}  // namespace lidar
}  // namespace perception
}  // namespace apollo
